﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Service;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Views;
using GalaSoft.MvvmLight.Command;
using System.Collections.ObjectModel;
using Common;
using MODEL;
using Microsoft.Practices.ServiceLocation;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using GalaSoft.MvvmLight.Ioc;

namespace ViewModel.AlertCreate
{
    public class AlertMakeEditViewModel : ViewModelBase
    {
        public ViewModelBase ParentViewModel { get; set; }

        private IAlertMakeService m_AlertMakeService;
        private IStationServcie m_StationService;
        private IElementService m_ElementService;

        private AlertMakeInfo m_AlertMakeInfo = new AlertMakeInfo();
        public AlertMakeInfo AlertMakeInfo
        {
            get { return m_AlertMakeInfo; }
            set { m_AlertMakeInfo = value; base.RaisePropertyChanged(); }
        }

        private string m_StationType;
        public string StationType
        {
            get { return m_StationType; }
            set { m_StationType = value; ResetDataOnStationChanged(); base.RaisePropertyChanged(() => StationType); }
        }

        private IEnumerable<string> m_StationTypeList;
        public IEnumerable<string> StationTypeList
        {
            get { return this.m_StationTypeList; }
            set { this.m_StationTypeList = value; base.RaisePropertyChanged(() => this.StationTypeList); }
        }

        private IEnumerable<StationInfo> m_StationList;
        public IEnumerable<StationInfo> StationList
        {
            get { return this.m_StationList; }
            set { m_StationList = value; base.RaisePropertyChanged(() => this.StationList); }
        }

        private IEnumerable<ElementInfo> m_ElementList;
        public IEnumerable<ElementInfo> ElementList
        {
            get { return this.m_ElementList; }
            set { m_ElementList = value; base.RaisePropertyChanged(() => this.ElementList); }
        }

        private Dictionary<string, List<StationInfo>> m_StationListDict = new Dictionary<string, List<StationInfo>>();
        private Dictionary<string, List<ElementInfo>> m_ElementListDict = new Dictionary<string, List<ElementInfo>>();

        public ICommand AddCommand { get; set; }       

        public void ResetDataOnStationChanged()
        {
            if (string.IsNullOrWhiteSpace(StationType))
            {
                return;
            }

            List<StationInfo> stationList = null;
            if (this.m_StationListDict.TryGetValue(this.StationType, out stationList))
            {
                this.StationList = stationList;
            }
            else
            {
                this.StationList = new List<StationInfo>();
            }

            List<ElementInfo> elementList = null;
            if (this.m_ElementListDict.TryGetValue(this.StationType, out elementList))
            {
                this.ElementList = elementList;
            }
            else
            {
                this.ElementList = new List<ElementInfo>();
            }
        }

        private void SyncDataWhenAlertInfoChange()
        {
            if (this.AlertMakeInfo == null)
            {
                this.StationType = null;
            }
            else
            {
                this.StationType = this.AlertMakeInfo.StationInfo.StationType;
                this.AlertMakeInfo.StationInfo = this.StationList.FirstOrDefault(station => station.StationId == AlertMakeInfo.StationInfo.StationId) ?? new StationInfo();
                this.AlertMakeInfo.ElementInfo = this.m_ElementList.FirstOrDefault(element => element.Id == AlertMakeInfo.ElementInfo.Id) ?? new ElementInfo();
            }
        }

        public AlertMakeEditViewModel(IAlertMakeService alertService, IStationServcie stationService, IElementService elementService)
        {
            this.m_AlertMakeService = alertService;
            this.m_StationService = stationService;
            this.m_ElementService = elementService;

            this.AddCommand = new RelayCommand(InsertAlert);
            RefreshData(() => { this.PropertyChanged += OnPropertyChange; });
        }

        public void OnPropertyChange(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName.Equals("StationType"))
            {
                ResetDataOnStationChanged();
            }

            if (e.PropertyName.Equals("AlertMakeInfo"))
            {
                SyncDataWhenAlertInfoChange();
            }
        }

        public async void RefreshData(Action afterRefresh = null)
        {
            try
            {
                IEnumerable<StationInfo> stations = await this.m_StationService.QueryStationsAsync(new StationQueryCriteria { UserId = AppSetting.Instance.User.UserId });
                this.StationTypeList = stations.Select(s => s.StationType).Distinct();

                this.m_StationListDict = stations.GroupBy(s => s.StationType).ToDictionary(group => group.Key, group => group.ToList());

                IEnumerable<ElementInfo> elements = await this.m_ElementService.QueryElementsAsync();
                this.m_ElementListDict = elements.GroupBy(e => e.StationType)?.ToDictionary(group => group.Key, group => group.ToList());
                if (afterRefresh != null)
                {
                    afterRefresh.Invoke();
                }
            }
            catch(Exception ex)
            {
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowError("加载数据失败", "错误", "确定", null);
            }
        }

        public async void InsertAlert()
        {
            if (string.IsNullOrWhiteSpace(this.AlertMakeInfo.Name))
            {
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowMessage("规则名称不能为空", "校验失败");
                return;
            }
            if (this.AlertMakeInfo.StationInfo == null)
            {
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowMessage("未选择站点", "校验失败");
                return;
            }

            if (this.AlertMakeInfo.ElementInfo == null)
            {
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowMessage("未选择要素", "校验失败");
                return;
            }

            if (!AlertMakeInfo.Month.HasValue || AlertMakeInfo.Month.Value < 0 || AlertMakeInfo.Month.Value > 12)
            {
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowMessage("月份信息输入错误", "校验失败");
                return;
            }

            if (this.AlertMakeInfo.MaxVal.HasValue && this.AlertMakeInfo.MinVal.HasValue && this.AlertMakeInfo.MaxVal < this.AlertMakeInfo.MinVal)
            {
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowMessage("最大值不能小于最小值", "校验失败");
                return;
            }

            this.AlertMakeInfo.CreateTime = DateTime.Now;
            this.AlertMakeInfo.AddMan = AppSetting.Instance.User.UserId;
            try
            {
                SimpleIoc.Default.GetInstance<IWaitingService>().StartWaitingAsync("正在保存");
                Task task = this.m_AlertMakeService.InsertOrUpdateAlertMakeInfo(AlertMakeInfo);
                task.Wait();
                SimpleIoc.Default.GetInstance<IWaitingService>().StopWaitingAsync();
              
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowMessage("保存成功", "提示").ContinueWith(t =>
                {
                    this.MessengerInstance.Send<object>(null, "AlertCreateEdit_CloseForm");
                    (this.ParentViewModel as AlertMakeViewModel)?.RefreshData();
                });
                
            }
            catch (Exception ex)
            {
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowError("保存失败", "错误", "确定", null);
                Log.WriteException(ex);
            }
        }
    }
}
